import numpy as np

def _circular_pad(arr, pad_len):
    """
    对数组进行循环填充，以处理边缘效应。
    """
    if pad_len == 0:
        return arr
    # 确保pad_len不会超过数组长度的一半，避免不必要的重复
    actual_pad_len = min(pad_len, len(arr) // 2) 
    return np.concatenate((arr[-actual_pad_len:], arr, arr[:actual_pad_len]))

def dwt_db2_decomposition(signal):
    """
    使用Daubechies 2 (db2) 小波对信号进行一级分解。
    
    参数:
    signal (np.array): 输入信号，一维numpy数组。
    
    返回:
    tuple: 包含近似系数 (approximations) 和细节系数 (details) 的元组。
    """
    print(f"\n--- 开始 Daubechies 2 (db2) 小波分解 ---")
    print(f"原始信号: {signal}")

    # db2小波的低通和高通滤波器系数
    # 近似数值，保留三位小数
    h = np.array([0.483, 0.837, 0.224, -0.129])  # 低通滤波器
    g = np.array([-0.129, -0.224, 0.837, -0.483]) # 高通滤波器

    print(f"低通滤波器 h: {h}")
    print(f"高通滤波器 g: {g}")

    N = len(signal)
    filter_len = len(h)

    approximations = []
    details = []

    # 卷积并下采样
    # 为了与手动计算的例子保持一致，我们直接模拟滑动窗口和点乘求和
    # 假设信号是周期性的，或者足够长，这里使用循环索引来模拟周期性
    for i in range(0, N, 2):
        # 计算近似系数
        approx_val = 0.0
        print(f"\n--- 计算第 {i//2 + 1} 组系数 (从索引 {i} 开始) ---")
        print(f"  原始信号片段 (循环): [{signal[i%N]}, {signal[(i+1)%N]}, {signal[(i+2)%N]}, {signal[(i+3)%N]}]")
        print(f"  低通滤波器 h: {h}")
        for k in range(filter_len):
            # 循环索引，确保在信号范围内
            idx = (i + k) % N 
            approx_val += signal[idx] * h[k]
            print(f"    近似项 {k}: {signal[idx]:.3f} * {h[k]:.3f} = {signal[idx]*h[k]:.3f}")
        approximations.append(approx_val)
        print(f"  近似系数 A[{i//2}]: {approx_val:.3f}")

        # 计算细节系数
        detail_val = 0.0
        print(f"  高通滤波器 g: {g}")
        for k in range(filter_len):
            # 循环索引，确保在信号范围内
            idx = (i + k) % N
            detail_val += signal[idx] * g[k]
            print(f"    细节项 {k}: {signal[idx]:.3f} * {g[k]:.3f} = {signal[idx]*g[k]:.3f}")
        details.append(detail_val)
        print(f"  细节系数 D[{i//2}]: {detail_val:.3f}")

    approximations = np.array(approximations)
    details = np.array(details)

    print(f"\n最终近似系数: {approximations}")
    print(f"最终细节系数: {details}")
    print(f"--- Daubechies 2 (db2) 小波分解完成 ---")

    return approximations, details

if __name__ == "__main__":
    # 示例信号
    signal = np.array([10, 12, 14, 16, 18, 20, 22, 24], dtype=float)
    
    # 执行分解
    approximations, details = dwt_db2_decomposition(signal)

    print("\n\n--- 总结 ---")
    print(f"原始信号: {signal}")
    print(f"分解后近似系数 (低频): {approximations}")
    print(f"分解后细节系数 (高频): {details}")

    # 注意：这里没有实现逆变换，因为重点是理解分解过程。
    # 逆变换需要使用重构滤波器，并且是上采样后卷积。

    # 实际应用中，可以使用pywt库进行小波变换，它提供了更完善和精确的实现。
    # import pywt
    # coeffs = pywt.dwt(signal, 'db2')
    # print(f"PyWavelets库计算结果 - 近似: {coeffs[0]}, 细节: {coeffs[1]}")